package com.biz.primus.ms.sms.service.internal;


import com.biz.primus.common.vo.SpringPageVO;
import com.biz.primus.model.misc.enums.ApiExceptionType;
import com.biz.primus.model.misc.utils.MessageTextUtils;
import com.biz.primus.model.misc.vo.SendTaskQuery;
import com.biz.primus.model.misc.vo.SendTaskVo;
import com.biz.primus.model.misc.vo.ShortMessageVo;
import com.biz.primus.ms.base.service.AbstractBaseService;
import com.biz.primus.ms.sms.dao.po.SendTask;
import com.biz.primus.ms.sms.dao.repository.SendTaskRepository;
import com.biz.primus.ms.sms.dao.sepecification.SendTaskSpecification;
import com.biz.primus.ms.sms.event.ApiExceptionEvent;
import com.biz.primus.ms.sms.event.ProviderNotAvailableEvent;
import com.biz.primus.ms.sms.event.SendMessageEvent;
import com.biz.primus.ms.sms.service.model.ServiceProvider;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author yanweijin
 * @date 2017/6/5
 */
@Service
@Slf4j
public class SendTaskService extends AbstractBaseService {

    private final SendTaskRepository sendTaskRepository;

    private final ChannelService channelService;

    @Autowired
    public SendTaskService(SendTaskRepository sendTaskRepository, ChannelService channelService) {
        this.sendTaskRepository = sendTaskRepository;
        this.channelService = channelService;
    }

    private Function<ShortMessageVo, SendTask> sendRequestTransfer = new Function<ShortMessageVo, SendTask>() {
        public SendTask apply(ShortMessageVo input) {
            SendTask sendTask = new SendTask();
            sendTask.setChannelCode(input.getChannelCode());
            sendTask.setChannelName(channelService.getChannelNameFromCache(input.getChannelCode()));
            sendTask.setContent(input.getContent());
            sendTask.setSignature(input.getSignature());
            sendTask.setReceiver(input.getMobile());
            sendTask.setSendRequestId(input.getRequestId());
            sendTask.setMessageType(input.getType());

            int length = StringUtils.length(input.getContent()) + StringUtils.length(input.getSignature()) + 2;
            int convertMessageNumber = length > 70 ? length % 67 + 1 : 1;
            sendTask.setConvertMessageNumber(convertMessageNumber);
            sendTask.setSignaturePosition(input.getSignaturePosition());
//			sendTask.setExtra(input.);
            return sendTask;
        }
    };


    @EventListener
    void handleSendEvent(SendMessageEvent event) {
        SendTask sendTask = sendRequestTransfer.apply(event.getShortMessageVo());
        ServiceProvider provider = event.getProvider();
        sendTask.setProviderId(provider.getProviderId());
        sendTask.setProviderName(provider.getProviderName());
        sendTask.setBatchNumber(event.getBatchNumber());
        sendTask.setId(idService.getNextId());
        sendTask.setSendResult(ApiExceptionType.SUCCESS);
        sendTaskRepository.persist(sendTask);
    }


    @EventListener
    void handlePNAEvent(ProviderNotAvailableEvent event) {
        SendTask sendTask = sendRequestTransfer.apply(event.getShortMessageVo());
        ServiceProvider provider = event.getProvider();
        sendTask.setProviderId(provider.getProviderId());
        sendTask.setProviderName(provider.getProviderName());
        sendTask.setId(idService.getNextId());
        sendTask.setSendResult(ApiExceptionType.PROVIDER_NOT_AVAILABLE);
        sendTaskRepository.persist(sendTask);
    }


    @EventListener
    void handleFELEvent(ApiExceptionEvent event) {
        SendTask sendTask = sendRequestTransfer.apply(event.getShortMessageVo());
        sendTask.setId(idService.getNextId());
        sendTask.setSendResult(event.getExceptionType());
        sendTask.setExtra(event.getExtraMessage());
        sendTaskRepository.persist(sendTask);
    }


    public SpringPageVO<SendTaskVo> query(SendTaskQuery query) {
        Pageable pageable = new PageRequest(query.getPage() - 1, query.getSize(), Sort.Direction.DESC, "id");
        Page<SendTask> taskPage = sendTaskRepository.findAll(new SendTaskSpecification(query), pageable);
        List<SendTaskVo> result = Lists.transform(taskPage.getContent(), sendTaskTransformer);
        return SpringPageVO.<SendTaskVo>builder().content(result)
                .totalElements(taskPage.getTotalElements())
                .size(query.getSize())
                .number(query.getPage())
                .build();

    }

    private Function<SendTask, SendTaskVo> sendTaskTransformer = new Function<SendTask, SendTaskVo>() {
        @Override
        public SendTaskVo apply(SendTask sendTask) {
            SendTaskVo vo = new SendTaskVo();
            vo.setChannelCode(sendTask.getChannelCode());
            vo.setChannelName(sendTask.getChannelName());
            vo.setCreateTimestamp(sendTask.getCreateTimestamp());
            vo.setMobile(sendTask.getReceiver());
            vo.setProviderId(sendTask.getProviderId());
            vo.setSendResultText(sendTask.getSendResult() == null ? "" : sendTask.getSendResult().getDesc());
            vo.setProviderName(sendTask.getProviderName());
            vo.setRequestId(sendTask.getSendRequestId());
            vo.setSendResult(sendTask.getSendResult());
            vo.setFullText(MessageTextUtils.getMessageFullText(sendTask.getSignaturePosition(), sendTask.getSignature(), sendTask.getContent()));
            return vo;
        }
    };

}
